﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.Server;
using Novacode;

namespace TestScribeExtended
{
    public partial class TestScribe : Form
    {
        private TfsTeamProjectCollection _tpc;
        private ProjectInfo _teamProject;
        private ITestManagementTeamProject _tmsProject;

        public TestScribe()
        {
            InitializeComponent();
        }

        private void TestScribe_Load(object sender, EventArgs e)
        {
            ResetForm();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            var tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
            if (tpp.ShowDialog() == DialogResult.OK)
            {
                _tpc = tpp.SelectedTeamProjectCollection;
                _teamProject = tpp.SelectedProjects[0];
                _tmsProject = _tpc.GetService<ITestManagementService>().GetTeamProject(_teamProject.Name);

                ResetForm();
                AddTfsConnectionDetails();
                AddTestPlansAndSuitesDetails();
            }
        }

        private void trvTestPlansTestSuites_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var tag = e.Node.Tag;
            if (tag is IRequirementTestSuite)
            {
                AddTestCases(((IRequirementTestSuite)tag).TestCases);
            }
            else if (tag is IStaticTestSuite)
            {
                AddTestCases(((IStaticTestSuite)tag).TestCases);                
            }
            else if (tag is IDynamicTestSuite)
            {
                AddTestCases(((IDynamicTestSuite)tag).TestCases);
            }
        }

        private void trvTestPlansTestSuites_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                SetNodes(e.Node, !e.Node.Checked);
                e.Cancel = true;
            }
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                List<TreeNode> testPlans = new List<TreeNode>();
                foreach (TreeNode node in trvTestPlansTestSuites.Nodes)
                {
                    if (node.Checked)
                    {
                        testPlans.Add(node);
                    }
                }
                new TestScribeGenerator().Generate(testPlans, _tmsProject, folderBrowserDialog.SelectedPath);
                MessageBox.Show("The test plan has been exported with success", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void ResetForm()
        {
            lblTfsCollectionValue.Text = string.Empty;
            lblTeamProjectValue.Text = string.Empty;
            trvTestPlansTestSuites.Nodes.Clear();
            lvTestCases.Items.Clear();
        }

        private void AddTfsConnectionDetails()
        {
            lblTfsCollectionValue.Text = _tpc.Uri.AbsoluteUri;
            lblTeamProjectValue.Text = _teamProject.Name;
        }

        private void SetNodes(TreeNode parentNode, bool isChecked)
        {
            parentNode.Checked = isChecked;
            foreach (TreeNode node in parentNode.Nodes)
            {
                SetNodes(node, isChecked);
            }
        }

        private void AddTestPlansAndSuitesDetails()
        {
            var testPlans = _tmsProject.TestPlans.Query("Select * From TestPlan");
            
            foreach (var testPlan in testPlans)
            {
                var testPlanNode = trvTestPlansTestSuites.Nodes.Add(testPlan.Name);
                testPlanNode.Tag = testPlan;
                AddTestSuites(testPlan.RootSuite.SubSuites, testPlanNode);

            }
            trvTestPlansTestSuites.ExpandAll();
        }

        private void AddTestCases(ITestSuiteEntryCollection testCaseCollection)
        {
            lvTestCases.Items.Clear();

            foreach (var testCase in testCaseCollection)
            {
                var listViewItem = new ListViewItem(testCase.Id.ToString());
                listViewItem.SubItems.Add(testCase.Title);
                lvTestCases.Items.Add(listViewItem);
            }
        }

        private void AddTestSuites(ITestSuiteCollection testSuiteCollection, TreeNode testNode)
        {
            foreach (var testSuite in testSuiteCollection)
            {
                var node = testNode.Nodes.Add(testSuite.Title);
                node.Tag = testSuite;

                if (testSuite.TestSuiteType == TestSuiteType.StaticTestSuite)
                {
                    var staticTestSuite = (IStaticTestSuite)testSuite;
                    if (staticTestSuite.Entries != null && staticTestSuite.Entries.Count > 0)
                    {
                        AddTestSuites(staticTestSuite.Entries, node);
                    }
                }
            }
        }

        private void AddTestSuites(ITestSuiteEntryCollection testSuiteEntryCollection, TreeNode testNode)
        {
            foreach (var testSuiteEntry in testSuiteEntryCollection)
            {
                
                if (testSuiteEntry.EntryType == TestSuiteEntryType.StaticTestSuite)
                {
                    var testSuite = (IStaticTestSuite)testSuiteEntry.TestSuite;
                    var node = testNode.Nodes.Add(testSuite.Title);
                    node.Tag = testSuite;

                    if (testSuite.Entries != null && testSuite.Entries.Count > 0)
                    {
                        AddTestSuites(testSuite.Entries, node);
                    }
                }
                else if (testSuiteEntry.EntryType == TestSuiteEntryType.RequirementTestSuite)
                {
                    var testSuite = (IRequirementTestSuite)testSuiteEntry.TestSuite;
                    var node = testNode.Nodes.Add(testSuite.Title);
                    node.Tag = testSuite;
                }
            }
        }

        

 





    }
}
